<?php

namespace app\task\command\mobile;

use api\mobile\Duojing36;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\console\input\Option;
use api\mobile\BaseModel;

/**
 * 【话费】订单推送到供应商
 */
class CreateSupplierOrder extends Command
{
    /**
     * 执行命令.
     * 
     * @param $supplierCode   供应商代号
     * 
     * sudo -uwww php /www/wwwroot/api/think mobile:createSupplierOrder --supplierCode $supplierCode
     */
    protected function configure()
    {
        $this->setName('mobile:createSupplierOrder')
            ->addOption('supplierCode', null, Option::VALUE_REQUIRED, 'supplier code')
            ->setDescription('push mobile order to supplier');
    }

    /**
     * 执行指令.
     *
     * @throws \think\admin\Exception
     */
    protected function execute(Input $input, Output $output)
    {
        $supplierCode = trim($input->getOption('supplierCode'));
        if (empty($supplierCode)) {
            echo '缺少参数 supplierCode' . PHP_EOL;
            return true;
        }

        $start = date('Y-m-d H:i:s');
        echo '[话费]开始下单: ' . $supplierCode  . PHP_EOL;
        $lockKey = 'create_mobile_supplier_order_lock_key_' . $supplierCode;
        $lockVal = cache($lockKey);
        if ($lockVal) {
            echo '还在处理呢' . PHP_EOL;

            return true;
        }

        cache($lockKey, 1, 1200);

        $api = Db::name('mobile_supplier')
            ->field('id, name, code, url, app_id, app_secret, balance')
            ->where('code', $supplierCode)
            ->where('is_deleted', 0)
            ->find();
        if (empty($api)) {
            echo '[话费]配置有误: ' . $supplierCode . PHP_EOL;
            cache($lockKey, null);

            return false;
        }

        $code = explode('-', $supplierCode)[0];
        $class = '\\api\\mobile\\' . ucfirst($code);
        if (!class_exists($class)) {
            echo '该供应商[' . $api['name'] . ']尚未对接: ' . $supplierCode . PHP_EOL;
            return false;
        }
        $model = new $class($api);

        // 账户余额小于 200，不跑了
        // if ($api['balance'] < 20000) {
        //     echo $api['name'] . '账户余额不足了' . $supplierCode . PHP_EOL;
        //     cache($lockKey, null);

        //     $balance = $model->queryAmount();
        //     if ($balance !== false) {
        //         Db::name('mobile_supplier')
        //             ->where('id', $api['id'])
        //             ->update([
        //                 'balance' => $balance,
        //             ]);
        //     }

        //     return false;
        // }

        $where = [];
        $where[] = ['supplier_status', '=', 1];
        $where[] = ['status', '=', 2];
        $where[] = ['mobile_supplier_id', '=', $api['id']];

        $done = 0;
        Db::name('mobile_order')
            ->field('id, sub_order_id, mobile, amount,
            settle_type, profit, settle_status, order_type')
            ->where($where)
            ->chunk(100, function ($list) use ($model, &$done) {
                if ($list->isEmpty()) {
                    return false;
                }

                foreach ($list as $order) {
                    $this->handleOrder($model, $order);
                    $done += 1;
                }
            });

        $end = date('Y-m-d H:i:s');
        $duration = strtotime($end) - strtotime($start);

        if (isProd()) {
            $balance = $model->queryAmount();
            if ($balance !== false) {
                Db::name('mobile_supplier')
                    ->where('id', $api['id'])
                    ->update([
                        'balance' => $balance,
                    ]);
            }
        }

        cache($lockKey, null);

        echo $api['name'] . '下单结束。处理了 ' . $done . ' 单 ' . $start . ' ~ ' . $end . ' 耗时：' . $duration . PHP_EOL;
    }

    private function handleOrder($model, $order)
    {
        /**
         * @var Duojing36 $model
         */
        $res = $model->create($order);
        $skip = false; // 是否跳过订单更新: true是 false否
        switch ($res['status']) {
            case BaseModel::SUCCESS: // 下单成功
                $update = [
                    'supplier_status' => 2,
                    'supplier_order_no' => $res['supplier_order_no'],
                    'supplier_order_create_time' => time(),
                    'remark' => '',
                ];
                break;
            case BaseModel::FAIL: // 下单失败
                $update = [
                    'supplier_status' => 99,
                    'remark' => $res['remark'],
                ];
                break;
            case BaseModel::LACK_OF_MONEY: // 余额不足
                $update = [
                    'supplier_status' => 99,
                    'remark' => $res['remark'],
                ];
                // $skip = true;
                break;
            case BaseModel::NEED_RETRY: // 需要重试，不能修改订单状态
                return 0;
                break;
            case BaseModel::RECHARGE_SUCCESS: // 充值成功
                // 充值成功了，没有回调了
                $status = $model->handleSuccess($order['id'], $res['supplier_order_no']);
                if (false === $status) {
                    echo $model->getError() . PHP_EOL;
                }
                return 1;
                break;
            case BaseModel::RECHARGE_FAIL: // 充值失败【空号，携号转网，虚拟号码，直接失败，不再重试】
                $status = $model->handleFail($order['id'], $res['remark']);
                if (false === $status) {
                    echo $model->getError() . PHP_EOL;
                }
                return 0;
                break;
            case BaseModel::NEED_CONFIRM: // 异常订单，人工确认
                $update = [
                    'supplier_status' => 21,
                    'remark' => '异常：'.$res['remark'].'联系客服确认',
                ];
                break;
            default:
                $skip = true;
                break;
        }

        if ($skip) {
            return 0;
        }

        $flag = Db::name('mobile_order')
            ->where('id', $order['id'])
            ->where('supplier_status', 1)
            ->update($update);
        if (!$flag) {
            echo '更新异常：' . json_encode($update) . PHP_EOL;
            return 0;
        }

        return 1;
    }
}
